package com.bluejie.bluej.java.thread;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.*;

public class CountDownLatchFCY {
    private int threadNum = 5;//执行任务的子线程数量
    private int workNum = 20;//任务数量
    private ExecutorService service;
    private ArrayBlockingQueue<String> blockingQueue;
    private static CountDownLatch latch;


    public static CountDownLatchFCY getInstance(){
        return new CountDownLatchFCY();
    }

    public void handle(){
        setUp();
        try {
            test();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    private void setUp() {
        service = Executors.newFixedThreadPool(threadNum, new ThreadFactoryBuilder().setNameFormat("bluej_td_%d").build());
        blockingQueue = new ArrayBlockingQueue<>(workNum);
        for (int i = 0; i < workNum; i++) {
            blockingQueue.add("任务-" + i);
        }
        latch = new CountDownLatch(workNum-1);//计数器的值为任务的数量
    }

    private void test() throws InterruptedException {
        for (int i = 0; i < workNum; i++) {
            service.execute(new WorkRunnable());
        }
        latch.await();//等待子线程的所有任务完成
        System.out.println("主线程去做其它事");
        //executorShudown();
        service.shutdown();
    }

    private void executorShudown(){
        if (service.isTerminated()){
            service.shutdown();
        }else {
            executorShudown();
        }
    }

    //用blockQueue中的元素模拟任务
    private String getWork() {
        return blockingQueue.poll();
    }

    class WorkRunnable implements Runnable {

        public void run() {
            String work = getWork();
            System.out.println("---"+Thread.currentThread().getName()+"----");
            performWork(work);
            latch.countDown();//完成一个任务就调用一次

        }
    }

    private void performWork(String work) {
        System.out.println("处理任务：" + work);
        try {
            //模拟耗时的任务
            Thread.currentThread().sleep(60);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}
